<script lang="ts">

let {
    data,
    children,
  }: {
    data: APIResourceListResponse
    children: any
  } = $props()
  
  import '../app.css'
  import {
    ButtonGroup,
    Button,
    Darkmode,
    Popover,
    Badge,
    Tooltip,
    Input,
    Label,
    Indicator,
    Alert,
    type BadgeColorType,
  } from 'svelte-5-ui-lib'
  import {
    AdjustmentsVerticalOutline,
    DownloadSolid,
    SearchOutline,
    CheckPlusCircleOutline,
    InfoCircleSolid,
  } from 'flowbite-svelte-icons'
  import { blur } from 'svelte/transition'
  import { httpMethodBadges, httpMethodColors } from '$lib/const'
  import CopyButton from '$lib/components/IconComponents/CopyButton.svelte'
  import { selectedAPIItem  } from '$lib/utils/stores.svelte'
  import type { APIResourceListResponse, APIResourceItem } from '$lib/api/types'
  import { setContext } from 'svelte'
  import { BaseUrls, ENV_STORAGE_KEY } from '$lib/utils/stores.svelte'
  import { BaseUrlContext } from '$lib/const.js'
  import { writable } from 'svelte/store'
  import { setStorage, getStorage } from '$lib/utils/stores'
  import { onMount } from 'svelte'
  
  let baseUrls = $state(BaseUrls)
  let currentEnv = writable(BaseUrls[0])

  // 页面加载时尝试从 localStorage 读取
  onMount(() => {
    const cached = getStorage(ENV_STORAGE_KEY, '')
    if (cached) {
      try {
        baseUrls = JSON.parse(cached)
        currentEnv.set(baseUrls[0])
        // 如果你用 currentEnv 作为 store，也同步 set 一下
      } catch {}
    }
  })
  
  setContext(BaseUrlContext, currentEnv)

  // 在每次 url 变更时持久化
  function persistEnvs() {
    setStorage(ENV_STORAGE_KEY, JSON.stringify(baseUrls))
  }

  let mockEndpoints = data.apiList.data

  selectedAPIItem.set(mockEndpoints?.[0])
  let apiItems = $state(mockEndpoints)
  let searchValue: string = $state('')

  let selectedEnvId = $state(BaseUrls[0].id)

  function lookFor() {
    const v: string = searchValue.trim()
    if (!v) apiItems = mockEndpoints
    apiItems = mockEndpoints.filter((api: APIResourceItem) => {
      if (
        api.method.toLowerCase() === v.toLowerCase() ||
        api.path.toLowerCase().includes(v.toLowerCase())
      ) {
        return true
      }
      return false
    })
  }

  function detectOS() {
    const userAgent = navigator.userAgent
    if (userAgent.includes('Win')) return 'windows'
    if (userAgent.includes('Mac')) return 'mac'
    return 'other'
  }
  function launchPostman() {
    const os = detectOS()
    let timer
    function triggerProtocol() {
      try {
        window.location.href = 'postman://'
        const iframe = document.createElement('iframe')
        iframe.style.display = 'none'
        iframe.src = 'postman://'
        document.body.appendChild(iframe)
        setTimeout(() => iframe.remove(), 100)
      } catch (e) {
        handleLaunchFailure(os)
      }
    }
    let appLaunched = false
    window.addEventListener('blur', () => (appLaunched = true))
    timer = setTimeout(
      () => {
        if (!appLaunched) handleLaunchFailure(os)
      },
      os === 'windows' ? 1500 : 800
    )
    triggerProtocol()
  }
  function handleLaunchFailure(os: string) {
    const downloadUrls = {
      windows: 'https://dl.pstmn.io/download/latest/win64',
      mac: 'https://dl.pstmn.io/download/latest/osx',
      other: 'https://www.postman.com/downloads/',
    }
    const confirmDownload = confirm(
      `Postman未安装，是否下载${os === 'windows' ? 'Windows' : 'Mac'}版？`
    )
    if (confirmDownload) {
      window.open(downloadUrls[detectOS()], '_blank')
    }
  }
</script>

<nav class="border-box fixed w-full z-20 top-0 start-0 bg-white dark:bg-gray-900 border-b border-gray-200 dark:border-gray-700 shadow-md dark:shadow-lg transition-all duration-200">
  <div class="flex items-center h-[96px] px-4 gap-4">
    <div class="basis-2/9">
      <Badge class="flex text-[32px] text-orange-800 dark:bg-transparent dark:text-orange-600 items-center gap-1.5 shrink-0 bg-transparent">
        <CheckPlusCircleOutline class="h-8 w-8" />
        Paramkit
      </Badge>
    </div>
    <div class="basis-full flex flex-end gap-3 overflow-x-auto">
      {#each httpMethodBadges as badge, i}
        <Label class="text-orange-600 dark:text-white hover:text-orange-500 transition-colors duration-150">
          {badge.method}
          <Badge
            color={badge.bgClass.split(' ')[0].replace('bg-', '') as BadgeColorType}
            rounded
            class={`${badge.bgClass} ${badge.textClass} ${badge.hoverClass} transition-colors duration-200 px-3 py-1 w-4 h-4 shadow-sm`}
          >
            <span class="font-xs">99</span>
          </Badge>
        </Label>
      {/each}
    </div>
    <div class="basis-4/9 flex items-center gap-2">
      <ButtonGroup class="w-80">
        <Input
        id="search-navbar"
        class="w-full bg-gray-50 dark:bg-gray-800 rounded-l-lg rounded-r-none focus:shadow-[inset_0_0_4px_1px_rgba(255,140,0,0.25)] focus:outline-none focus:ring-0 border-none transition-all duration-150"
        bind:value={searchValue}
        placeholder="I C U ..."
        onkeydown={(event) => {
          if (event.key === 'Enter') {
            event.preventDefault()
            lookFor()
          }
        }}
      />
        <Button color="primary" class="!p-2.5 rounded-r-lg rounded-l-none shadow-sm" type="button" onclick={lookFor}>
          <SearchOutline class="h-5 w-5" />
        </Button>
      </ButtonGroup>
    </div>
  </div>
</nav>

<div class="box-border flex gap-3 pt-[120px] h-screen">
  <aside class="pl-2 w-[18vw] flex flex-col bg-red ">
    <div class="flex-none mb-2 bg-white dark:bg-gray-800 rounded-xl shadow-xl border border-gray-100 !dark:border-gray-800 p-3 transition-all duration-200">      
      <ul class="flex gap-2">
        {#each baseUrls as env}
          <li>
            <button
              type="button"
              class={`px-3 py-1 rounded-md border transition-colors duration-150 text-xs font-bold ${selectedEnvId === env.id ? 'bg-orange-500 text-white border-orange-500 shadow' : 'bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-200 border-gray-200 dark:border-gray-700'}`}
              onclick={() => {
                    selectedEnvId = env.id
                    currentEnv.set(env);
                    persistEnvs();
              }}
            >
              {env.label}
            </button>
          </li>
        {/each}
      </ul>
      <ul class="mt-3">
        {#each baseUrls as env}
          <li class="mb-2">
            <Input
              size="sm"
              class={`!pr-8 !text-[14px]/[14px] !border-none !bg-gray-50 !rounded-md dark:!bg-gray-700 mt-1 mb-2 shadow-sm focus:ring-2 focus:ring-orange-400 dark:focus:ring-orange-500 transition-all duration-150 ${selectedEnvId === env.id ? 'bg-orange-500  text-xs font-bold text-orange-600 border-orange-500 shadow' : 'bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-200 border-gray-200 dark:border-gray-700'}`}
              type="text"
              placeholder={env.placeholder}
              value={env?.url}
              required
              title={env?.url}
              disabled={selectedEnvId !== env.id}
              oninput={e => {
                const target = e.target as HTMLInputElement | null;
     
                if (target) {
                  env.url = target.value;
                  currentEnv.set(env);
                  persistEnvs();
                }
              }}
            >
              {#snippet right()}
                <CopyButton text={env?.url} />
              {/snippet}
            </Input>
          </li>
        {/each}
      </ul>
    </div>
    <div class="flex-1 shadow-lg border-none box-border h-full p-1 scrollbar-hide scroll-smooth overflow-y-auto rounded-xl border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900 transition-all duration-200">      <div class="divide-y list-none divide-gray-200 border-none bg-white dark:divide-gray-700 dark:border-gray-700 dark:bg-gray-900 min-h-30 rounded-xl">
        {#if apiItems.length == 0}
          <Alert color="red" class="!items-start rounded-lg shadow-sm">
            {#snippet icon()}
              <InfoCircleSolid class="mt-1 h-5 w-5" />
            {/snippet}
            <p class="text-lg font-medium">Nothing Found.</p>
            <p class="mt-2 mb-4 text-sm">What are you doing? 这里不是无人区!!!</p>
          </Alert>
        {/if}
        {#each apiItems as apiItem, i}
          <a
            href="/"
            class="p-0 m-[1px] box-border h-[32px] flex items-center gap-1 group border-0 "
            onclick={() => {
              selectedAPIItem.set(apiItem)
            }}
          >
            <span
              class={`w-7 h-7 flex items-center justify-center rounded-md font-bold text-white text-xs shadow transition-all duration-150 bg-${httpMethodColors[apiItem.method as keyof typeof httpMethodColors]}-500 group-hover:bg-${httpMethodColors[apiItem.method as keyof typeof httpMethodColors]}-600`}
            >
              {apiItem.method.charAt(0).toUpperCase()}
            </span>
            <Label
              id={apiItem.id}
              class="overflow-x-hidden truncate w-full list-none hover:bg-orange-50 dark:hover:bg-gray-700 rounded-lg px-2 py-1 transition-colors duration-150"
            >
              {apiItem.endpoint}
            </Label>
            <Tooltip triggeredBy={`#${apiItem.id}`} position="right">
              {apiItem.endpoint}
            </Tooltip>
          </a>
        {/each}
      </div>
    </div>
  </aside>
  <main class="box-border w-[calc(100vw-24vw)]">
    {@render children()}
  </main>
</div>

<Darkmode class="fixed top-8 right-8 z-30" />

<ButtonGroup class="fixed right-4 bottom-4 *:ring-primary-700!">
  <Popover
    class="w-64 text-sm font-light "
    title="Open Local Postman"
    triggeredBy="#postman-open-btn"
    transition={blur}
    params={{ duration: 100 }}>打开本地postman软件</Popover>
  <Button id="postman-open-btn" onclick={launchPostman} class="rounded-lg shadow-sm">
    <AdjustmentsVerticalOutline class="w-4 h-4 me-2" />
    Postman
  </Button>
  <Popover
    class="w-64 text-sm font-light "
    title="Markdown API Docs"
    triggeredBy="#markdown-download-btn"
    transition={blur}
    params={{ duration: 100 }}>下载全部接口markdown文档</Popover>
  <Button
    id="markdown-download-btn"
    onclick={() => {
      window.location.href = '/download'
    }}
    class="rounded-lg shadow-sm"
  >
    <DownloadSolid class="w-4 h-4 me-2" />
    Markdown
  </Button>
</ButtonGroup>

<style>
  .scrollbar-hide {
    scrollbar-width: none;
    &::-webkit-scrollbar {
      display: none;
      width: 0;
      height: 0;
      background: transparent;
    }
  }
  .sticky {
    position: sticky;
    transition: top 0.3s ease-in-out;
    scroll-margin-top: 100px;
    scroll-behavior: smooth;
    scroll-snap-type: y proximity;
  }
  @media (prefers-color-scheme: dark) {
    .sticky {
      background: rgba(17, 24, 39, 0.95);
      backdrop-filter: blur(10px);
    }
  }
</style>